/*
 * Copyright 2009 Eat Local Food, LLC
 * Copyright (c) 2007 osCommerce (this file was written after
 * code review of osCommerce).
 *
 * This file is part of gwtCommerce.
 *
 * gwtCommerce is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * gwtCommerce is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with gwtCommerce.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.elf.gwt.common.client.model;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONValue;

public class CategoryModel extends AbstractModel
{	
	protected CategoryMetaModel categoryMetaModel;
	protected int id;
	protected String name;
	protected String image;
	protected String[] imageSize;
	protected int parentId;
	protected CategoryModel parentModel;
	protected int count;
	protected int categoriesPerRowMax;
	protected boolean rebuildCategoryComponent;
	protected boolean hideEmptyCategories;
	protected Date dateAdded;
	protected Date lastModified;
	protected int sortOrder;
	protected int errorCode;
	protected String message;
	protected List<CategoryModel> childList; 
	protected int[] productIds;
	protected List<DetailedProductModel> products;

	public CategoryModel()
	{
		categoryMetaModel = null;
		id = 0;
		name = "TBD"; 
		image = "";
		imageSize = new String[2];
		imageSize[0] = "1";
		imageSize[1] = "1";
		parentId = 0;
		parentModel = null;
		count = 0;
		categoriesPerRowMax = 5;
		rebuildCategoryComponent = false;
		hideEmptyCategories = false;
		dateAdded = null;
		lastModified = null;
		sortOrder = 0;
		errorCode = 0;
		message = "";
		childList = new ArrayList<CategoryModel>();
		productIds = new int[0];
		products = new ArrayList<DetailedProductModel>();
		}
	
	public CategoryModel(int id, String name, String image, String[] imageSize, int parentId, CategoryModel parentModel, int count, int categoriesPerRowMax, boolean hideEmptyCategories)
	{
		this();
		update(id, name, image, imageSize, parentId, parentModel, null, count, productIds, categoriesPerRowMax, false, hideEmptyCategories);
	}

	public CategoryModel(JSONObject jsonObject, CategoryMetaModel categoryMetaModel)
	{
		this();
		this.categoryMetaModel = categoryMetaModel;
		update(jsonObject);
	}	
	
	public void update(JSONObject jsonObject)
	{
		id = convertToInteger(jsonObject, "id");
		name = convertToString(jsonObject, "name");
		image = convertToString(jsonObject, "image");
		parentId = convertToInteger(jsonObject, "parent_id");
		count = convertToInteger(jsonObject, "count");
		dateAdded = convertToDate(jsonObject, "date_added");
		lastModified = convertToDate(jsonObject, "last_modified");
		sortOrder = convertToInteger(jsonObject, "sort_order");
		errorCode = convertToInteger(jsonObject, "error_code");
		message = convertToString(jsonObject, "message");

		if (image.length() > 0)
		{
			double imageWidth = convertToDouble(jsonObject, "image_width");
			double imageHeight = convertToDouble(jsonObject, "image_height");
			imageSize = adjustedImageSize(imageWidth, imageHeight, categoryMetaModel.getImageWidthMax(), categoryMetaModel.getImageHeightMax());
		}
		categoriesPerRowMax = categoryMetaModel.getCategoriesPerRowMax();
		hideEmptyCategories = categoryMetaModel.isHideEmptyCategories();
		
		buildProductIds(jsonObject);
		buildProducts(jsonObject);
	}

	protected void buildProductIds(JSONObject jsonObject)
	{
		try {
			JSONValue addressValue = jsonObject.get("products");

			if (addressValue != null)
			{
				JSONArray jsonArray;
				if ((jsonArray = addressValue.isArray()) != null)
				{
			
					int sz = jsonArray.size();
					productIds = new int[sz];
					for (int i = 0; i < sz; i++)
					{
						JSONValue jsonValue = jsonArray.get(i);
						JSONObject jsonPObject;
						if ((jsonPObject = jsonValue.isObject()) != null)
						{
							int productId = AbstractModel.convertToInteger(jsonPObject, "id");
							productIds[i] = productId;
						}
					}
				}
			}
		}
		catch (Exception e) {}
	}

	protected void buildProducts(JSONObject jsonObject)
	{
		products.clear();
		try {
			JSONValue productsValue = jsonObject.get("products");

			if (productsValue != null)
			{
				JSONArray jsonArray;
				if ((jsonArray = productsValue.isArray()) != null)
				{
					int sz = jsonArray.size();
					for (int i = 0; i < sz; i++)
					{
						JSONValue jsonValue = jsonArray.get(i);
						JSONObject jsonPObject;
						if ((jsonPObject = jsonValue.isObject()) != null)
						{
							DetailedProductModel model = new DetailedProductModel(jsonPObject, this.categoryMetaModel.getImageWidthMax(), this.categoryMetaModel.getImageHeightMax(), true);
							products.add(model);
						}
					}
				}
			}
		}
		catch (Exception e) {}
	}
	
	public void update(CategoryModel model)
	{
		update(model.getId(), model.getName(), model.getImage(), model.getImageSize(), model.getParentId(), model.getParentModel(), 
				model.getChildList(), model.getCount(), model.getProductIds(), model.getCategoriesPerRowMax(), model.isRebuildCategoryComponent(), model.isHideEmptyCategories());
		
	}

	public void update(int id, String name, String image, String[] imageSize, int parentId, CategoryModel parentModel, 
			List<CategoryModel> childList, int count, int[] productIds, int categoriesPerRowMax, boolean rebuildCategoryComponent, boolean hideEmptyCategories)
	{
		this.id = id;
		this.name = name;
		this.image = image;
		if (imageSize != null) this.imageSize = imageSize;
		this.parentId = parentId;
		this.parentModel = parentModel;
		if (childList != null) this.childList = childList;
		this.count = count;
		if (productIds != null) this.productIds = productIds;
		this.categoriesPerRowMax = categoriesPerRowMax;
		this.rebuildCategoryComponent = rebuildCategoryComponent;
		this.hideEmptyCategories = hideEmptyCategories;
	}
	
	public int getCategoriesPerRowMax() {
		return categoriesPerRowMax;
	}
	
	public List<CategoryModel> getChildList() {
		return childList;
	}
	
	public int getCount() {
		return count;
	}

	public int getId() {
		return id;
	}

	public String getImage() {
		return image;
	}
	
	public String[] getImageSize() {
		return imageSize;
	}
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public int getParentId() {
		return parentId;
	}
	
	public void setParentId(int parentId)
	{
		this.parentId = parentId;
	}
	
	public CategoryModel getParentModel() {
		return parentModel;
	}
	
	public int getProductIdIndex(int productId) {
		int index = 0;
		
		for (int i = 0; i < productIds.length; i++)
		{
			if (productId == productIds[i])
			{
				index = i;
				break;
			}
		}
		return index;
	}

	public int[] getProductIds() {
		return productIds;
	}

	public boolean isHideEmptyCategories() {
		return hideEmptyCategories;
	}

	public boolean isRebuildCategoryComponent() {
		return rebuildCategoryComponent;
	}

	public void setCount(int count) {
		this.count = count;
	}

	public void setParentModel(CategoryModel parentModel) {
		this.parentModel = parentModel;
	}

	public void setProductIds(int[] productIds) {
		this.productIds = productIds;
	}

	public void setRebuildCategoryComponent(boolean rebuildCategoryComponent) {
		this.rebuildCategoryComponent = rebuildCategoryComponent;
	}

	public Date getDateAdded() {
		return dateAdded;
	}

	public Date getLastModified() {
		return lastModified;
	}

	public int getSortOrder() {
		return sortOrder;
	}

	public int getErrorCode() {
		return errorCode;
	}

	public void setErrorCode(int errorCode) {
		this.errorCode = errorCode;
	}
	
	public String getMessage() {
		return message;
	}
	
	public void setMessage(String message) {
		this.message = message;
	}

	public List<DetailedProductModel> getProducts() {
		return products;
	}

	public CategoryMetaModel getCategoryMetaModel() {
		return categoryMetaModel;
	}

	public void setCategoryMetaModel(CategoryMetaModel categoryMetaModel) {
		this.categoryMetaModel = categoryMetaModel;
	}
}
